#pragma once

#include "utils/optimized_spread_history.h"
#include "utils/memory_pool.h"
#include <string>
#include <unordered_map>
#include <memory>
#include <mutex>
#include <vector>

namespace hft {

/**
 * @brief 交易对标识符
 * 
 * 用于唯一标识一个交易对。
 */
struct PairIdentifier {
    std::string symbol1;  // 第一个交易品种
    std::string symbol2;  // 第二个交易品种

    /**
     * @brief 构造函数
     * @param s1 第一个交易品种
     * @param s2 第二个交易品种
     */
    PairIdentifier(const std::string& s1, const std::string& s2)
        : symbol1(s1 < s2 ? s1 : s2)
        , symbol2(s1 < s2 ? s2 : s1) {
    }

    /**
     * @brief 相等运算符
     */
    bool operator==(const PairIdentifier& other) const {
        return symbol1 == other.symbol1 && symbol2 == other.symbol2;
    }
};

/**
 * @brief 交易对标识符的哈希函数
 */
struct PairIdentifierHash {
    size_t operator()(const PairIdentifier& pair) const {
        return std::hash<std::string>()(pair.symbol1) ^ 
               (std::hash<std::string>()(pair.symbol2) << 1);
    }
};

/**
 * @brief 优化的多价差历史管理器
 * 
 * 这个类管理多个交易对的价差历史，使用内存池和SIMD优化来提高性能。
 */
class OptimizedMultiSpreadHistory {
public:
    /**
     * @brief 构造函数
     * @param default_capacity 默认容量
     */
    explicit OptimizedMultiSpreadHistory(size_t default_capacity = 1000)
        : default_capacity_(default_capacity) {
    }

    /**
     * @brief 添加价差
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     * @param spread 价差
     */
    void addSpread(const std::string& symbol1, const std::string& symbol2, double spread) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        PairIdentifier pair(symbol1, symbol2);
        auto it = spread_histories_.find(pair);
        
        if (it == spread_histories_.end()) {
            // 创建新的价差历史
            auto history = std::make_shared<OptimizedSpreadHistory>(default_capacity_);
            spread_histories_[pair] = history;
            it = spread_histories_.find(pair);
        }
        
        it->second->addSpread(spread);
    }

    /**
     * @brief 获取特定交易对的价差历史
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     * @return 价差历史指针
     */
    std::shared_ptr<OptimizedSpreadHistory> getSpreadHistory(
        const std::string& symbol1, const std::string& symbol2) const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        PairIdentifier pair(symbol1, symbol2);
        auto it = spread_histories_.find(pair);
        
        if (it != spread_histories_.end()) {
            return it->second;
        }
        
        return nullptr;
    }

    /**
     * @brief 获取所有交易对
     * @return 交易对列表
     */
    std::vector<PairIdentifier> getPairs() const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        std::vector<PairIdentifier> pairs;
        pairs.reserve(spread_histories_.size());
        
        for (const auto& pair : spread_histories_) {
            pairs.push_back(pair.first);
        }
        
        return pairs;
    }

    /**
     * @brief 获取特定交易对的价差数量
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     * @return 价差数量
     */
    size_t getCount(const std::string& symbol1, const std::string& symbol2) const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        PairIdentifier pair(symbol1, symbol2);
        auto it = spread_histories_.find(pair);
        
        if (it != spread_histories_.end()) {
            return it->second->getCount();
        }
        
        return 0;
    }

    /**
     * @brief 获取特定交易对的最新价差
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     * @return 最新价差
     */
    double getLatestSpread(const std::string& symbol1, const std::string& symbol2) const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        PairIdentifier pair(symbol1, symbol2);
        auto it = spread_histories_.find(pair);
        
        if (it != spread_histories_.end()) {
            return it->second->getLatestSpread();
        }
        
        return 0.0;
    }

    /**
     * @brief 计算特定交易对的移动平均价差
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     * @param window_size 窗口大小
     * @return 移动平均价差
     */
    double calculateSMA(const std::string& symbol1, const std::string& symbol2, size_t window_size) const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        PairIdentifier pair(symbol1, symbol2);
        auto it = spread_histories_.find(pair);
        
        if (it != spread_histories_.end()) {
            return it->second->calculateSMA(window_size);
        }
        
        return 0.0;
    }

    /**
     * @brief 计算特定交易对的标准差
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     * @param window_size 窗口大小
     * @return 标准差
     */
    double calculateStdDev(const std::string& symbol1, const std::string& symbol2, size_t window_size) const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        PairIdentifier pair(symbol1, symbol2);
        auto it = spread_histories_.find(pair);
        
        if (it != spread_histories_.end()) {
            return it->second->calculateStdDev(window_size);
        }
        
        return 0.0;
    }

    /**
     * @brief 计算特定交易对的Z-Score
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     * @param window_size 窗口大小
     * @return Z-Score
     */
    double calculateZScore(const std::string& symbol1, const std::string& symbol2, size_t window_size) const {
        std::lock_guard<std::mutex> lock(mutex_);
        
        PairIdentifier pair(symbol1, symbol2);
        auto it = spread_histories_.find(pair);
        
        if (it != spread_histories_.end()) {
            return it->second->calculateZScore(window_size);
        }
        
        return 0.0;
    }

    /**
     * @brief 清除特定交易对的价差历史
     * @param symbol1 第一个交易品种
     * @param symbol2 第二个交易品种
     */
    void clear(const std::string& symbol1, const std::string& symbol2) {
        std::lock_guard<std::mutex> lock(mutex_);
        
        PairIdentifier pair(symbol1, symbol2);
        auto it = spread_histories_.find(pair);
        
        if (it != spread_histories_.end()) {
            it->second->clear();
        }
    }

    /**
     * @brief 清除所有价差历史
     */
    void clearAll() {
        std::lock_guard<std::mutex> lock(mutex_);
        
        for (auto& pair : spread_histories_) {
            pair.second->clear();
        }
    }

private:
    size_t default_capacity_;  // 默认容量
    std::unordered_map<PairIdentifier, std::shared_ptr<OptimizedSpreadHistory>, PairIdentifierHash> spread_histories_;  // 价差历史映射表
    mutable std::mutex mutex_;  // 互斥锁
};

} // namespace hft